#pragma once
#include <iostream>
#include "Log.hpp"
#include <sys/epoll.h>
#include <unistd.h>
#include "Comm.hpp"
using namespace std;
static const int gsize = 128;
class Epoller
{
private:
    bool EventMethodCore(int fd, uint32_t events, int type)
    {
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;
        // 将此fd的指定event事件修改进入epoll红黑树
        int n = epoll_ctl(_epfd, type, fd, &ev);
        if (n < 0)
        {
            LOG(ERROR, "epoll_ctl [fd:%d-events:%d]失败\n", fd, events);
            return false;
        }
        LOG(INFO, "epoll_ctl [fd:%d-events:%d]成功\n", fd, events);
        return true;
    }

public:
    Epoller()
    {
        _epfd = epoll_create(gsize);
        if (_epfd < 0)
        {
            LOG(FATAL, "epoll模型创建失败\n");
            exit(EPOLL_CREAT_ERROR);
        }
        LOG(DEBUG, "epoll模型创建成功 epfd:%d\n", _epfd);
    }

    // 添加指定fd的指定事件
    bool AddEvent(int fd, uint32_t events)
    {
        return EventMethodCore(fd, events, EPOLL_CTL_ADD);
    }
    // 修改指定fd要关心的事件
    bool ModEvent(int fd, uint32_t events)
    {
        return EventMethodCore(fd, events, EPOLL_CTL_MOD);
    }
    // 删除指定fd要关心的事件
    bool DelEvent(int fd)
    {
        return epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
    }

    // 等待事件就绪
    int Wait(struct epoll_event revs[], int num, int timeout)
    {
        int n = epoll_wait(_epfd, revs, num, timeout);
        return n;
    }
    ~Epoller()
    {
        if (_epfd >= 0)
        {
            // 释放epoll模型对象
            close(_epfd);
        }
    }

private:
    int _epfd; // epoll模型-fd
};